//
//  TGMModel2ViewAdapter.m
//  TravelGuideMdd
//
//  Created by HanFeng on 3/12/14.
//  Copyright (c) 2014 mafengwo.com. All rights reserved.
//

#import "TGMModel2ScrollViewAdapter.h"
#import "TGMBasePullToRefreshHandler.h"

@implementation TGMModel2ScrollViewAdapter

- (void)dealloc
{
    if (_scrollView.tgm_delegateForPullToRefresh == self.pullToRefreshHandler) {
        [self cleanPullToRefreshFacadeStyle];
    }
    
    [self.currentOperationTask cancel];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
    }
    return self;
}

- (BOOL)supportPullRefreshHeader
{
    return NO;
}

- (BOOL)supportGetMoreFooter
{
    return NO;
}

- (UIEdgeInsets)contextScrollViewContentInset
{
    return UIEdgeInsetsZero;
}

// 初始代码触发刷新
- (void)triggerRefresh
{
    if ([self isRefreshLoading])
    {
        return;
    }
    
    if ([self supportPullRefreshHeader])
    {
        [_scrollView triggerPullToRefresh];
    }
    else
    {
        UIEdgeInsets inset = [self contextScrollViewContentInset];
        [_scrollView setContentOffset:CGPointMake(0, -inset.top)];
        
        [self requestRefresh];
    }
}

- (void)cancelRefresh;
{
    if (self.currentOperationTask)
    {
        if (self.currentOperationTask.dataRequestType == kMFWDataRequest_Refresh)
        {
            [self.currentOperationTask cancel];
            self.currentOperationTask = nil;
            
            if ([self supportPullRefreshHeader])
            {
                [_scrollView tgm_stopPullToRefreshAnimating];
            }
        }
    }
}

- (void)requestRefresh
{
    [self.currentOperationTask cancel];
    
    self.currentOperationTask = [self startRefreshRequest];
    if (self.currentOperationTask)
    {
        //success start refreshing
        _refreshLoading = YES;
        _refreshError = NO;
        
        if ([self.delegate respondsToSelector:@selector(adapterDidRefresh:)])
        {
            [self.delegate adapterDidRefresh:self];
        }
    }
}

- (void)requestGetMore
{
    // 如果有别的请求（无论刷新或者更多）没有完成，则放弃取更多的请求
    if (self.currentOperationTask)
    {
        return;
    }

    self.currentOperationTask = [self startGetMoreRequest];
}

#pragma mark - template methods, subclass should override these methods as needed

- (TGMBaseModelActionData*)actionDataForRequestModelData:(MFWDataRequestType)type
{
    [NSException raise:@"NotImplemented:" format:@"[%@]actionDataForRequestModelData:",NSStringFromClass([self class])];
    return nil;
}

- (MFWTask*)startRefreshRequest
{
    [NSException raise:@"NotImplemented:" format:@"[%@]startRefreshRequest:",NSStringFromClass([self class])];
    return nil;
}

- (MFWTask*)startGetMoreRequest
{
    [NSException raise:@"NotImplemented:" format:@"[%@]startGetMoreRequest:",NSStringFromClass([self class])];
    return nil;
}

- (void)buildListData
{
    [NSException raise:@"NotImplemented:" format:@"[%@]buildListData:",NSStringFromClass([self class])];
}

- (void)reloadUIData:(BOOL)refreshed byRequestType:(MFWDataRequestType)type;
{
    [NSException raise:@"NotImplemented:" format:@"[%@]reloadUIData:byRequestType:",NSStringFromClass([self class])];
}


#pragma mark - MFWDataObserver
- (void)requestFinishedForTask:(MFWTask*)task withModel:(MFWDataModel*)model dataId:(NSString*)dataId requestType:(MFWDataRequestType)type itemArray:(NSArray*)itemArray success:(BOOL)bSuccess error:(NSError*)error;
{
    if ([task isEqual:self.currentOperationTask] && [_actionData.dataId isEqualToString:dataId])
    {
        if ([self.delegate respondsToSelector:@selector(adapter:didFinishRequest:withError:)])
        {
            [self.delegate adapter:self didFinishRequest:type withError:error];
        }
        
        if (type == kMFWDataRequest_Refresh)
        {
            _refreshError = (error != nil);
            _refreshLoading = NO;
            
            self.currentOperationTask = nil;
            
            if ([self supportPullRefreshHeader])
            {
                if ([self.pullToRefreshHandler stopAnimationManually:bSuccess] == NO) {
                    [_scrollView tgm_stopPullToRefreshAnimating];
                    [self requirePullToRefreshFacadeStyle];
                }
            }
            [self onRefreshFinished:error data:itemArray];
        }
        else
        {
            self.currentOperationTask = nil;
            [self onGetMoreFinished:error data:itemArray];
        }
    }
}

#pragma mark Request Result Handler

- (void)onRefreshFinished:(NSError*)error data:(NSArray*)array
{
    if (!error)
    {
        [self buildListData];
        [self reloadUIData:YES byRequestType:kMFWDataRequest_Refresh];
    }
    else
    {
        [self reloadUIData:NO byRequestType:kMFWDataRequest_Refresh];
    }
}

- (void)onGetMoreFinished:(NSError*)error data:(NSArray*)array
{
    if (!error)
    {
        [self buildListData];
        [self reloadUIData:YES byRequestType:kMFWDataREquest_GetMore];
    }
    else
    {
        [self reloadUIData:NO byRequestType:kMFWDataREquest_GetMore];
    }
}


#pragma mark - Pull to Refresh

- (NSString *)pageNameForPullToRefresh
{
    return [self.contextViewController pageName];
}

- (NSString *)filterKeyForPullToRefresh
{
    return nil;
}

- (BOOL)asyncRequirePullToRefreshFacadeStyle
{
    return YES;
}

- (void)cleanPullToRefreshFacadeStyle
{
    self.pullToRefreshHandler = nil;
}

- (void)stopPullToRefreshLoadingAnimating:(BOOL)refreshSuccess
{
    if ([self supportPullRefreshHeader])
    {
        if ([self.pullToRefreshHandler stopAnimationManually:refreshSuccess] == NO) {
            [_scrollView tgm_stopPullToRefreshAnimating];
            [self requirePullToRefreshFacadeStyle];
        }
    }
}

- (void)requirePullToRefreshFacadeStyle
{
    if ([self supportPullRefreshHeader] == NO) return;
    
//    NSString *name = self.pageNameForPullToRefresh;
//    NSString *filterKey = self.filterKeyForPullToRefresh;
    BOOL async = [self asyncRequirePullToRefreshFacadeStyle];
    
    if (self.pullToRefreshHandler == nil && async) {
        self.pullToRefreshHandler = [[TGMBasePullToRefreshHandler alloc] init];
        [self.pullToRefreshHandler loadResources];
    }
    
//    if (config == nil || config.isAPNGFileReady == NO) {
        if ([self.pullToRefreshHandler isKindOfClass:[TGMBasePullToRefreshHandler class]] == NO) {
            self.pullToRefreshHandler = [[TGMBasePullToRefreshHandler alloc] init];
            [self.pullToRefreshHandler loadResources];
        }
//    } else {
//        if (_pullToRefreshHandler == nil) {
//            UIEdgeInsets inset = [self contextScrollViewContentInset];
//            [_scrollView setContentOffset:CGPointMake(0, -inset.top)];
//        }
//        
//        if (self.scrollView.pullToRefreshView.isAnimating == NO
//            && _lockForAsyncLoadAPImageView == NO) {
//
//            ScenarioAnimatedRefreshHandler *handler = (id)self.pullToRefreshHandler;
//            if ([handler isKindOfClass:[ScenarioAnimatedRefreshHandler class]] == NO
//                || config != handler.configuration) {
//                
//                _lockForAsyncLoadAPImageView = YES;
//                [[ScenarioPullToRefreshManager sharedInstance] loadAPImageViewForConfiguration:config withFrame:self.scrollView.pullToRefreshView.bounds getter:^(APImageView *imageView) {
//
//                    if (imageView == nil || config.apngFilePath.length == 0) {
//                        _lockForAsyncLoadAPImageView = NO;
//                        return;
//                    };
//                    
//                    BaseBlock block = ^{
//                        // 未显示出来下拉刷新的view，且，在loading中
//                        if (self.scrollView.pullToRefreshView.percentForPullToRefresh <= 0.01
//                            && self.scrollView.pullToRefreshView.isAnimating == NO) {
//                            ScenarioAnimatedRefreshHandler *newHandler = [[ScenarioAnimatedRefreshHandler alloc] init];
//                            newHandler.configuration = config;
//                            newHandler.viewAdapter = self;
//                            
//                            self.pullToRefreshHandler = newHandler;
//                            newHandler.refreshView.apImageView = imageView;
//                            [self.pullToRefreshHandler loadResources];
//                        }
//                        
//                        _lockForAsyncLoadAPImageView = NO;
//                    };
//                    
//                    if (async == NO) {
//                        block();
//                    } else {
//                        // 尝试两次，第一次是置于下拉动画之后1s，第二次是如遇其他另外情况再等1s
//                        // 两次尝试是为了滚动加载机制导致的过度重复加载而浪费资源
//                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//                            block();
//                            if (_lockForAsyncLoadAPImageView) {
//                                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), block);
//                            }
//                        });
//                    }
//                } async:async];
//            }
//        }
//    }
}

- (void)setPullToRefreshHandler:(TGMBasePullToRefreshHandler *)pullToRefreshHandler
{
    _pullToRefreshHandler = pullToRefreshHandler;
    
    DLog(@"%@ 的 PullToRefreshHandler 变化为 %@", self, _pullToRefreshHandler);
    
    _pullToRefreshHandler.viewAdapter = self;
    [self.scrollView tgm_clearPullToRefresh];
    [self.scrollView tgm_initializePullToRefreshWithDelegate:_pullToRefreshHandler userInfo:nil];
}

#pragma mark - UIScrollViewDelegate Implementations
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (self.pullToRefreshHandler) {
        // 为了延时替换，仅在已经设置了handler之后滚动替换
        [self requirePullToRefreshFacadeStyle];
    }
    
    if ([self.delegate respondsToSelector:@selector(adapterDidScroll:)]) {
        [self.delegate adapterDidScroll:self];
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (self.pullToRefreshHandler) {
        // 为了延时替换，仅在已经设置了handler之后滚动替换
        [self requirePullToRefreshFacadeStyle];
    }
}

#pragma mark - ScenarioPullToRefreshManagerObserver
- (void)scenarioConfigurationsDidRefresh
{
    [self requirePullToRefreshFacadeStyle];
}

@end
